/// <reference path="../../Scripts/typings/disco/disco.d.ts" />
/// <reference path="../viewmodels/shell.ts" />

import _app = require('durandal/app');

import _ko = require('knockout');

import _disco = require('disco');

import _shell = require('../viewmodels/shell');

class DiscoViewModel {
    public parameters: any = null;

    public discoContext: _disco.Context = null;

    public isLoading: KnockoutObservable<boolean>;

    public exceptions: KnockoutObservableArray<string>;

    constructor(discoUri?: string) {
        console.debug('ViewModel Create.');

        this.exceptions = _ko.observableArray<string>([]);
        this.isLoading = _ko.observable<boolean>(true);

        if (!discoUri || ('' == discoUri)) {
            discoUri = 'http://dev.disco-network.local/api/odata';
            //discoUri = 'http://localhost:50256/api/odata';
            //discoUri = 'http://test.disco-network.org/api/odata';
        }

        this.discoContext = new _disco.Context(discoUri);

        this.exceptions.subscribe((newValue: string[]) => {
            _app.showMessage(newValue.shift(), "An error occured!");
        });
    }

    public activate(parameters: any) {
        console.debug('ViewModel Activate. URL parameters [' + JSON.stringify(parameters) + ']');

        this.parameters = parameters;

        return true;
    }

    public onError(error: any) {
        this.isLoading(false);

        // TODO: As a User I want to see a user-friendly error message, so that I don't need to read json formatted error objects.

        console.error(error);

        var message = 'The page might be in an inconsitent state. Please reload the page to prevent loss of data. ' + error;
        this.exceptions.push(message);
    }

    public loadPosts(
        query: (it: Disco.Ontology.Post) => boolean,
        args: any,
        callback?: (data: Disco.Ontology.Post[]) => void,
        additionalIncludes?: string[]): $data.IPromise<Disco.Ontology.Post[]> {

        var posts: $data.Queryable<Disco.Ontology.Post> = this.discoContext.Posts;

        var includes: string[] = ['Content'];
        if (additionalIncludes) jQuery.merge(includes, additionalIncludes);

        includes.forEach(property => posts = posts.include(property));

        posts = posts.filter(query, args);

        var promise = posts.toArray().then((data: Disco.Ontology.Post[]) => {
            console.debug('Load Posts: Data Arrived.');

            if (callback) {
                console.debug('Load Posts: Execute Callback.');
                callback(data);
            }
        }).fail((error: any) => {
            this.onError(error);
        });

        return promise;
    }
}

export = DiscoViewModel;